package servlet;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.jsonschema2pojo.SchemaMapper;

import com.sun.codemodel.JCodeModel;

/**
 * 上传Json格式文件并转换为Java类 转换现在还有问题
 * 
 * @author wanhongchang
 *
 */
public class FileUploadServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	@SuppressWarnings("rawtypes")
	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		// 使用Common-upload
		FileItemFactory itemFactory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(itemFactory);
		String className = "";
		String packageName = "";
		try {
			// 请求的参数
			List items = upload.parseRequest(request);
			//
			Iterator itr = items.iterator();
			while (itr.hasNext()) {
				FileItem item = (FileItem) itr.next();
				// 判断请求参数是文件还是表单
				if (item.isFormField()) {
					System.out.println("表单参数名:" + item.getFieldName()
							+ "，表单参数值:" + item.getString("UTF-8"));
					if ("targetpackage".equals(item.getFieldName())) {
						packageName = item.getString("UTF-8");
					} else if ("classname".equals(item.getFieldName())) {
						className = item.getString("UTF-8");
					}
				} else {
					// 页面编码
					response.setCharacterEncoding("gbk");
					// 检查表单是否为空
					if (checkInputInfo(response, packageName, className)) {
						if (!item.getName().isEmpty()) {
							// 判断文件是否为json格式文件
							if ("json".equals(item.getName().substring(
									item.getName().lastIndexOf(".") + 1))) {
								// 文件名
								String fileName = item.getName();
								// 获取服务的路径
								String path = request.getServletContext()
										.getRealPath("/WEB-INF/upload");
								// // 创建文件
								File file = new File(path, fileName);
								try {
									item.write(file);
								} catch (Exception e) {
									response.getWriter().write("创建文件失败");
									return;
								}
								// 将JSON格式转化为Java类
								JCodeModel codeModel = new JCodeModel();
								URL url = file.toURI().toURL();
								new SchemaMapper().generate(codeModel,
										className, "java", url);
								codeModel.build(new File(path));
								//
								// response.getWriter().write("文件转换OK!");
								//
								getFileList(request, response);
							} else {
								response.getWriter().write("文件格式不正确");
							}
						} else {
							response.getWriter().write("请选择上传的文件");
						}
					} else {
						return;
					}

				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void getFileList(HttpServletRequest request,
			HttpServletResponse response)throws Exception {
		// 获取上传文件的目录
		String uploadFilePath = this.getServletContext().getRealPath(
				"/WEB-INF/upload/java");
		// 存储要下载的文件名
		Map<String, String> fileNameMap = new HashMap<String, String>();
		// 递归遍历filepath目录下的所有文件和目录，将文件的文件名存储到map集合中
		listfile(new File(uploadFilePath), fileNameMap);// File既可以代表一个文件也可以代表一个目录
		// 将Map集合发送到listfile.jsp页面进行显示
		request.setAttribute("fileNameMap", fileNameMap);
		request.getRequestDispatcher("/filelist.jsp")
				.forward(request, response);
	}

	private boolean checkInputInfo(HttpServletResponse response,
			String packageName, String className) throws IOException {
		if (packageName.isEmpty()) {
			response.getWriter().write("包名不能为空");
			return false;
		} else if (className.isEmpty()) {
			response.getWriter().write("类名不能为空");
			return false;
		}
		return true;
	}

	public boolean isEmpty(String fileName) {
		if (fileName != null && !fileName.equals("")) {
			return false;
		}
		return true;
	}

	public void listfile(File file, Map<String, String> map) {
		// 如果file代表的不是一个文件，而是一个目录
		if (!file.isFile()) {
			// 列出该目录下的所有文件和目录
			File files[] = file.listFiles();
			// 遍历files[]数组
			for (File f : files) {
				// 递归
				listfile(f, map);
			}
		} else {
			String realName = file.getName();
			// file.getName()得到的是文件的原始名称，这个名称是唯一的，因此可以作为key，realName是处理过后的名称，有可能会重复
			map.put(file.getName(), realName);
		}
	}

}
